jetcrab\parser\statements/
control_flow.rs

1use crate::ast::{
2    BreakStatement, CatchClause, ContinueStatement, Node, ThrowStatement, TryStatement,
3};
4use crate::lexer::TokenKind;
5use crate::parser::error::ParseResult;
6use crate::parser::Parser;
7
8impl Parser {
9    pub fn parse_break_statement(&mut self) -> ParseResult<Node> {
10        self.advance();
11
12        let label = if self.check_identifier() {
13            Some(Box::new(self.parse_identifier()?))
14        } else {
15            None
16        };
17
18        let span = self.create_span_from_tokens();
19        Ok(Node::BreakStatement(BreakStatement {
20            label,
21            span: Some(span),
22        }))
23    }
24
25    pub fn parse_continue_statement(&mut self) -> ParseResult<Node> {
26        self.advance();
27
28        let label = if self.check_identifier() {
29            Some(Box::new(self.parse_identifier()?))
30        } else {
31            None
32        };
33
34        let span = self.create_span_from_tokens();
35        Ok(Node::ContinueStatement(ContinueStatement {
36            label,
37            span: Some(span),
38        }))
39    }
40
41    pub fn parse_throw_statement(&mut self) -> ParseResult<Node> {
42        self.advance();
43
44        let argument = Box::new(self.parse_expression()?);
45
46        let span = self.create_span_from_tokens();
47        Ok(Node::ThrowStatement(ThrowStatement {
48            argument,
49            span: Some(span),
50        }))
51    }
52
53    pub fn parse_try_statement(&mut self) -> ParseResult<Node> {
54        self.advance();
55
56        let block = Box::new(self.parse_block_statement()?);
57
58        let handler = if let Some(token) = &self.current {
59            if let TokenKind::Keyword(kw) = &token.kind {
60                if kw == "catch" {
61                    Some(Box::new(self.parse_catch_clause()?))
62                } else {
63                    None
64                }
65            } else {
66                None
67            }
68        } else {
69            None
70        };
71
72        let finalizer = if let Some(token) = &self.current {
73            if let TokenKind::Keyword(kw) = &token.kind {
74                if kw == "finally" {
75                    self.advance();
76                    Some(Box::new(self.parse_block_statement()?))
77                } else {
78                    None
79                }
80            } else {
81                None
82            }
83        } else {
84            None
85        };
86
87        let span = self.create_span_from_tokens();
88        Ok(Node::TryStatement(TryStatement {
89            block,
90            handler,
91            finalizer,
92            span: Some(span),
93        }))
94    }
95
96    pub fn parse_catch_clause(&mut self) -> ParseResult<Node> {
97        self.advance();
98
99        self.expect(TokenKind::LeftParen)?;
100        let param = Box::new(self.parse_identifier()?);
101        self.expect(TokenKind::RightParen)?;
102
103        let body = Box::new(self.parse_block_statement()?);
104
105        let span = self.create_span_from_tokens();
106        Ok(Node::CatchClause(CatchClause {
107            param,
108            body,
109            span: Some(span),
110        }))
111    }
112}